package model.framework;

public class Frame extends SurfaceHelper {
	
	private int fieldx; // x position of this frame in the field
	private int height; // height of the frame
	private int[] dimensions; // amount this frame can hold
	
	/**
	 * creates a frame with the dimensions
	 * @param size
	 */
	public Frame( int[] dimensions, int fieldx, int height) {
		this.dimensions = dimensions;
		this.height = height;
		this.fieldx = fieldx;
	}
	
	/**
	 * @return x coordinate of frame in field
	 */
	public int getFieldx() {
		return fieldx;
	}
	
	/**
	 * @return height of this frame
	 */
	public int getHeight() {
		return height;
	}
	
	/**
	 * @return height of this frame
	 */
	public int getWidth() {
		return dimensions.length;
	}
	
	/**
	 * @return the dimensions of this frame
	 */
	public int[] getDimensions() {
		return dimensions;
	}

	/**
	 * Adds one row to the frame
	 */
	public void addRow() {
		this.height++;
	}
	
	/**
	 * @param block
	 * @param rotation
	 * @return dimensions of space remaining in top of the frame
	 */
	public int[] storageAfterPlacing( BlockType block, int rotation ) {
		return dimensions;
	}
	
	/**
	 * @return returns the 
	 */
	public int[] getSurfaceAboveLowest(){
		int[] surface = new int[dimensions.length];
		
		int lowest = this.calculateLowestSurface( dimensions );
		
		/* Subtract lowest from every y */
		for( int iDim = 0; iDim < dimensions.length; iDim++ ){
			surface[iDim] = dimensions[iDim] - lowest;
		}
		
		return surface;
	}
	
	/**
	 * 
	 * @param block
	 * @param rotation
	 * @return
	 */
	public int[] getSurfaceBelowBlockAfterPlacing( Block block, int rotation ){
		
		int[] newDimensions = new int[dimensions.length];
		int[] blockSurface = block.getSurface( rotation );
		int[] lowestSurface = getSurfaceAboveLowest();
		
		for( int iSurface = 0; iSurface < lowestSurface.length; iSurface++ ) {
			newDimensions[ iSurface ] = lowestSurface[ iSurface ] + ( block.getBlockType().getHeight(rotation) - blockSurface[ iSurface ]);
		}
		
		int highestAfterPlacing = this.calculateHighestSurface( newDimensions );

		for( int iSurface = 0; iSurface < newDimensions.length; iSurface++ ) {
			newDimensions[ iSurface ] = highestAfterPlacing - newDimensions[ iSurface ];
		}
		
		return newDimensions;
	}
	
	/**
	 * @param block
	 * @param rotation
	 * @return returns the height of this frame after placing a block and -1 if the block doesn't fit in the frame
	 */
	public int heightAfterPlacing( Block block, int rotation ){
		return this.heightAfterPlacing(block, rotation, true);
	}
	
	/**
	 * @param block
	 * @param rotation
	 * @param minusOne true or false, decides wether or not -1 is returned if a block does not fit
	 * @return returns the height of this frame after placing of a block or -1 if it doesnt fit and minusOne is true
	 */
	public int heightAfterPlacing( Block block, int rotation, boolean minusOne ){
		int[] blockSurface = block.getSurface( rotation );
		int afterPlacedHeight = -1;
		
		/* Walk through the frame and up the height with the blocksurface */
		for( int iframeWidth=0; iframeWidth < dimensions.length; iframeWidth++ ){
			
			/* The height of the block is reduced by it's surface because the surface is the empty space beneath the block */
			int placedHeight = dimensions[iframeWidth] + (block.getBlockType().getHeight(rotation) - blockSurface[iframeWidth]);
			
			/* If a bigger height is found, safe it */
			if(  placedHeight > afterPlacedHeight ){
				afterPlacedHeight = placedHeight;
			}
		}
		
		if( minusOne && (afterPlacedHeight > this.height) ){
			return -1;
		}
		
		return afterPlacedHeight;
	}
	
	/**
	 * toString gives textual representation of the block
	 */
	public String toString(){
		String string = "";
		
		for( int iframeWidth=0; iframeWidth < dimensions.length; iframeWidth++ ){
			string += "|" + dimensions[iframeWidth];
		}

		string += "| height: " + this.height;
		
		return string;
	}
	
}
